
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/join.hpp>
#include <boost/format.hpp>

#include "henry.hpp"

using namespace boost;

/* Global variables. */
progress_bar_t     g_progress_bar;
variable_manager_t g_vm;
int                g_verbose_level = 1;

/* Implementations. */
string literal_t::to_string( literal_repr_t repr_type ) const {

  static char buffer[1024];
    
  switch( repr_type ) {
        
  case Literal:
    return (format( "%s(%s)" ) % predicate % g_vm.join( arguments, "," )).str();

  case LiteralOrgArgs:
    return (format( "%s(%s)" ) % predicate % g_vm.join( o_arguments, "," )).str();
        
  case PredicateArity: {
    sprintf( buffer, "%s/%d", predicate.c_str(), (int)arguments.size() );
    return string( buffer ); };
        
  case OrgArgs: {
    if( "!=" == predicate ) return g_vm.p2v( o_arguments[0] ) + " != " + g_vm.p2v( o_arguments[1] );
    sprintf( buffer, "%s(%s):%.2f:%s:{%s}", predicate.c_str(), g_vm.join( o_arguments, "," ).c_str(), number, named.c_str(), merged_with.c_str() );
    return string( buffer ); };
      
  default: {
    if( "!=" == predicate ) return g_vm.p2v( arguments[0] ) + " != " + g_vm.p2v( arguments[1] );
    sprintf( buffer, "%s(%s):%.2f:%s:{%s}", predicate.c_str(), g_vm.join( arguments, "," ).c_str(), number, named.c_str(), merged_with.c_str() );
    return string( buffer ); };
  }
    
}

string literal_list_t::to_string() const {
  string_list_t str_literal_list;
    
  for( literal_list_t::const_iterator iter=this->begin(); this->end()!=iter; ++iter )
    str_literal_list.push_back( iter->to_string() );
      
  return join( str_literal_list, ", " );
}

string literal_vector_t::to_string() const {
  string_list_t str_literal_list;
      
  for( literal_vector_t::const_iterator iter=this->begin(); this->end()!=iter; ++iter )
    str_literal_list.push_back( iter->to_string() );
      
  return join( str_literal_list, ", " );
}

string unifier_list_t::to_string() const {
  string_list_t sl;
    
  for( unifier_list_t::const_iterator iter_u = this->begin(); this->end() != iter_u; ++iter_u )
    sl.push_back( g_vm.p2v( iter_u->v1 ) + "=" + g_vm.p2v( iter_u->v2 ) );
    
  return join( sl, ", " );
}

string unifier_operator_t::to_string( const unifier_t *p_storage ) const {
  string_list_t sl_unifiers;
  foreachc( int_list_t, iter_u, unifiers ) {
    sl_unifiers.push_back( p_storage[ *iter_u ].to_string() );
  }
  return (is_postponed ? "C.U. " : "") + join( sl_unifiers, ", " );
}

